Chapter 28 - Terraform Modules - Existing
Using modules from the Terraform Registry
Modules are a collection of resource that are built together. These are the main way to package and reuse configurations in Terraform.
The root module can call child modules.
You can include modules from the local filesystem or from public or private repositories.
Use Public Modules
Git Repo 49 is used here.
In production, always lock the module version To implement a vnet module from the registry, such as: https://registry.terraform.io/modules/Azure/vnet/azurerm/latest
From the Terraform registry, you should be able to find any module and include that module using the block that is highlighted on the Module Registry page.
Note: Ctrl+Space does not work in modules. You would need to define the inputs from the Terraform Registry. Sometimes, there are examples you can copy. I copied and modified those below:
module "vnet_1" {
source = "Azure/vnet/azurerm"
version = "4.0.0" #always lock version in production
vnet_name = local.vnet_name
resource_group_name = azurerm_resource_group.rg_1.name
address_space = ["10.0.0.0/16"]
subnet_prefixes = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
subnet_names = ["subnet01", "subnet02", "subnet03"]
subnet_service_endpoints = {
subnet02 = ["Microsoft.Storage", "Microsoft.Sql"],
subnet03 = ["Microsoft.AzureActiveDirectory"]
}
tags = {
environment = "dev"
region = "centralus"
id = "123"
}
depends_on = [azurerm_resource_group.rg_1]
}
You can now create the normal resources such as public IP or NIC below this in the .tf file for the networking code.
Referencing the module in your new code is done as follows:
resource "azurerm_network_interface" "mynic" {
name = local.nic_name
location = azurerm_resource_group.myrg.location
resource_group_name = azurerm_resource_group.myrg.name
ip_configuration {
name = "internal"
subnet_id = module.vnet.vnet_subnets[0] ## here
private_ip_address_allocation = "Dynamic"
public_ip_address_id = azurerm_public_ip.mypublicip.id
}
tags = local.common_tags
}
Module Outputs
You can define the values as below, note the top one is not from a module, and the bottom two are.
# VM
output "vm_public_ip_address" {
description = "My Virtual Machine Public IP"
value = azurerm_linux_virtual_machine.mylinuxvm.public_ip_address
}
# VNet Name
# virtual_network_name
output "virtual_network_name" {
description = "Virtual Network Name"
value = module.vnet.vnet_name
}
# VNet ID
output "virtual_network_id" {
description = "Virtual Network ID"
value = module.vnet.vnet_id
}
Init, Validate, Plan, and Apply
When you run a terraform init
on the dir with the modules, TF will download the modules and create a couple of key things:
- modules dir
- modules.json
Results of the terraform init
:
Files created:
From here, run your sequence of Validate, Plan and Apply
Run a terraform state list
to see how these module resources look differently from the normal resources.
Tainting Module
You cannot taint an entire module, you must taint individual resources.
terraform state list
terraform taint module.vnet.vnet
Meta Arguments
You can still use meta arguments within modules:
- count
- for_each
- providers
- depends_on
- lifecycle
Note about Module Sources
https://developer.hashicorp.com/terraform/language/modules/sources
- local paths
- github
- bitbucket
- S3 buckets